package com.summer.core.common;

import java.lang.reflect.Method;
import java.util.Properties;

import org.apache.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.util.StringUtils;

import com.summer.core.entity.BaseBean;
/**
 * 日志aop切面  
 * 	<!-- 需要在  applicationContext里加下面   使用AspectJ方式配置AOP -->
	<aop:aspectj-autoproxy proxy-target-class="true" />
 * @author wwwlike
 *
 */
//@Aspect //①通过该注解将PreGreetingAspect标识为一个切面 
public class LogAop {
	
    private Logger logger;//日志句柄   
    
    private String loggerName;//日志名称   
  
    private Properties properties;//属性文件句柄   

	


	@Pointcut("execution(* com.blue.people.service..*.*(..))")
	public void myMethod() {
	}// 声
	
	
	
	@Before("myMethod() && args(name)")
	// 括号中的名字就是切入点定义的方法名
	public void beforeAdvice(String name) {
	   System.out.println("前置通知！" + name);
	}

	@AfterReturning(pointcut = "myMethod()", returning = "result")
	// 上下名称要相同，它的意思是说返回值为String类型，并把返回值赋予变量"result"
	public void afterReturnAdvice(String result) {
	   System.out.println("后置通知！" + result);
	}

	@After("myMethod()")
	public void afterAdvice() {
	   System.out.println("最终通知！");
	}

	@AfterThrowing(pointcut = "myMethod()", throwing = "e")
	public void exceptionAdvice(Exception e) {
	   System.out.println("异常通知！" + e);
	}

	@Around("myMethod()")
	// 这个通知的方法参数类型必须是ProceedingJoinPoint类型,方法名可以自定义，如下所示
	public Object aroundAdvice(ProceedingJoinPoint pjp) throws Throwable {
	   System.out.println("进入方法！");
	   Object target=pjp.getTarget();
	   Method method=getMethod(pjp);
	   UserOperateLog anno = method.getAnnotation(UserOperateLog.class);   
	   for(int i=0;i<pjp.getArgs().length;i++)
	   {
		   
		   //判断此类是否是实体类
		   if(pjp.getArgs()[i].getClass().newInstance() instanceof BaseBean)
		   {
			   BeanName beanname= pjp.getArgs()[0].getClass().getAnnotation(BeanName.class);
			   String name=beanname.value();
//			   System.out.println( name);
		   }
	   }
	   
     if (anno!= null)   
     {
     String defaultMessage = anno.value();   
     String methodName = target.getClass().getName() + "."  
             + method.getName();   
     String desc = this.handleDescription(anno.key(), StringUtils   
             .hasText(defaultMessage) ? defaultMessage : methodName);   
     //装配日志信息   
//     String logline = this.buildLogLine(username, anno.type(), desc);   
     }
	   
	  
	   //执行目标对象的方法
	   Object object = pjp.proceed();
	   System.out.println("退出方法！");
	   return object;
	}
	
	 /**  
     * 获取日志内容描述，可以从消息配置文件中找到对应的信息  
     *   
     * @param key  
     *            日志内容key  
     * @param defaultMessage  
     *            默认的描述信息  
     * @return 描述信息  
     */  
    protected String handleDescription(String key, String defaultMessage) {   
        if (properties == null)   
            return defaultMessage;   
        if (!StringUtils.hasText(key))   
            return defaultMessage;   
        String message = properties.getProperty(key);   
        if (!StringUtils.hasText(message))   
            return defaultMessage;   
        else  
            return message;   
    }   
  
    private Method getMethod(ProceedingJoinPoint pjp)
    {
	String methodName = pjp.getTarget().getClass().getName() + "" + pjp.getSignature().getName();

	// 从缓存中抓取Method
	Method method = OpLogCache.methodMap.get(methodName);

	// Method未记录到缓存
	if (method == null)
	{
	    //只记录接口注解
	    Class<?>[] clazzs = pjp.getTarget().getClass().getInterfaces();
	    for (Class<?> c : clazzs)
	    {
		Method[] ms = c.getMethods();
		for (Method m : ms)
		{
		    if (m.getName().equals(pjp.getSignature().getName()))
		    {
			method = m;
			break;
		    }
		}
		if (method != null)
		{
		    break;
		}
	    }

	    // 缓存Method
	    OpLogCache.methodMap.put(methodName, method);
	}
	return method;
    }
}
